#include "base/channel.h"
#include "base/eventloop.h"
#include "base/log.h"
#include "base/config.h"

#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>

#include "base/logfile.h"
namespace net_tools::base{
Logfile::Logfile(std::string app_name,net_tools::Eventloop* eventloop,FILE* file_stream)
  :app_name_(std::move(app_name)),
   eventloop_(eventloop),
   pid_(getpid()),
   index_(0),
   tm_buf{0},
   filename_(),
   fd_stream_(nullptr),
   logbuffer_(this,eventloop_),
   use_file_(false),
   write_size_(0)
{
  if(file_stream){
    Setstream(file_stream);
  }else{
    Use_file_flush_file();
  }
};
Logfile::~Logfile(){
};
//如果之前没有使用file 则使用 否则滚动日志
void Logfile::Use_file_flush_file(){
  if(!use_file_){
    Creatfile();
  }else{
    Rollfile();
  }
};
// 如果之前使用file 则关闭 设为新的FILE
void Logfile::Setstream(FILE* stream){
  logbuffer_.Set_fd(stream);
  int flag = access(filename_.c_str(),F_OK);
  if(flag == 0){
    Endfile();
  }
  fd_stream_ = stream;
};
void Logfile::Flush(){
  if(use_file_){
    write_size_ += logbuffer_.Flush();
    if(write_size_ >= _C::SET_LOG_SET_FILE_MAX_SIZE){
      Rollfile();
    }
  }else{
    logbuffer_.Flush();
  }
};
void Logfile::Output(void* address,short int len){
  logbuffer_.Output(address,len);
};
void Logfile::Creatfile(){
  gettimeofday(&begin_time_,NULL);
  struct tm tm_time_;
  localtime_r(&begin_time_.tv_sec,&tm_time_);
  strftime(tm_buf,128,"%F-%T--",&tm_time_);
  filename_ = app_name_ + ":" + std::to_string(pid_) + ":" + tm_buf;
  NT_LOG_INFO << "Change Log file to:" << filename_ << NT_LOG_ENDL;
  fd_stream_ = fopen(filename_.c_str(),"w");
  write_size_ = 0;
  use_file_ = true;
  logbuffer_.Set_fd(fd_stream_);
};
void Logfile::Endfile(){
  fflush(fd_stream_);
  gettimeofday(&end_time_,NULL);
  struct tm tm_time_;
  localtime_r(&end_time_.tv_sec,&tm_time_);
  strftime(tm_buf,128,"%F-%T",&tm_time_);
  std::string old = filename_;
  filename_ += tm_buf;
  filename_ += "_" + std::to_string(index_);
  logbuffer_.Set_fd(stderr);
  use_file_ = false;
  fclose(fd_stream_);
  rename(old.c_str(),filename_.c_str());
  filename_.clear();
  ++index_;
};
void Logfile::Rollfile(){
  NT_LOG_INFO << "Roll Log file" << NT_LOG_ENDL;
  fflush(fd_stream_);
  gettimeofday(&end_time_,NULL);
  begin_time_.tv_sec = end_time_.tv_sec;
  struct tm tm_;
  localtime_r(&end_time_.tv_sec,&tm_);
  //创建新的文件
  strftime(tm_buf,128,"%F-%T--",&tm_);
  std::string new_filename = app_name_ + ":" + std::to_string(pid_) + ":" + tm_buf;
  FILE* new_stream = fopen(new_filename.c_str(),"w");
  write_size_ = 0;
  logbuffer_.Set_fd(new_stream);
  //改名
  std::string old = filename_;
  strftime(tm_buf,128,"%F-%T",&tm_);
  filename_ += tm_buf;
  filename_ += "_" + std::to_string(index_);
  ++index_;
  fclose(fd_stream_);
  rename(old.c_str(),filename_.c_str());
  //更新
  filename_ = std::move(new_filename);
  fd_stream_ = new_stream;
};

} // namespace net_tools::base
